package com.example.bigupload.manager;

import com.example.bigupload.mapper.FileInfoMapper;
import io.minio.MinioClient;
import io.minio.GetObjectArgs;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class MinioManagerService {

    @Autowired
    private MinioClient minioClient;
    @Resource
    private FileInfoMapper fileInfoMapper;

    private String bucketName="filetest";

    // 下载文件并压缩为 ZIP 文件
    public File downloadAndZipFiles() throws ExecutionException, InterruptedException, IOException {
        List<String> fileNames=fileInfoMapper.getAll().stream().map(auth->auth.getFilePath()).collect(Collectors.toList());
            String tempDirPath = "C:\\Users\\lenovo\\Desktop\\123" + File.separator + "minio_temp_" + UUID.randomUUID();
            File tempDir = new File(tempDirPath);
            if (!tempDir.mkdir()) {
                throw new RuntimeException("Failed to create temp directory: " + tempDirPath);
            }

            // 使用 CompletableFuture 处理多线程下载
            CompletableFuture<Void>[] futures = new CompletableFuture[fileNames.size()];
            for (int i = 0; i < fileNames.size(); i++) {
                final String fileName = fileNames.get(i);
                futures[i] = CompletableFuture.runAsync(() -> downloadFileToTempDir(fileName, tempDir));
            }

            // 等待所有下载完成
            CompletableFuture<Void> allOf = CompletableFuture.allOf(futures);
            allOf.get();  // 阻塞，直到所有下载完成

            return tempDir;
        }

        // 压缩临时目录为 ZIP 文件
        public File zipDirectory(File directory) throws IOException {
            String zipFilePath = directory.getPath() + ".zip";
            File zipFile = new File(zipFilePath);

            try (FileOutputStream fos = new FileOutputStream(zipFile);
                 ZipOutputStream zipOut = new ZipOutputStream(fos)) {
                for (File file : directory.listFiles()) {
                    try (InputStream fileInputStream = Files.newInputStream(file.toPath())) {
                        zipOut.putNextEntry(new ZipEntry(file.getName()));
                        copy(fileInputStream, zipOut);
                        zipOut.closeEntry();
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException("Error occurred during ZIP compression", e);
            }

            return zipFile;
        }

        // 上传文件到 MinIO
        public String uploadFileToMinio(File file, String objectName) throws Exception {
            try (InputStream inputStream = new FileInputStream(file)) {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(inputStream, file.length(), -1)
                        .contentType("application/zip")
                        .build());
            }
            return objectName;
        }

        // 下载文件到临时目录
        private void downloadFileToTempDir(String fileName, File tempDir) {
            try (InputStream inputStream = minioClient.getObject(
                    GetObjectArgs.builder().bucket(bucketName).object(fileName).build())) {
                File tempFile = new File(tempDir, fileName);
                try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
                    byte[] buffer = new byte[8192];
                    int length;
                    while ((length = inputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, length);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException("Error occurred while downloading file: " + fileName, e);
            }
        }

        // 自定义 copy 方法
        private void copy(InputStream input, OutputStream output) throws IOException {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = input.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
        }

        // 删除目录及其内容
        public void deleteDirectory(File directory) {
            if (directory.isDirectory()) {
                for (File file : directory.listFiles()) {
                    deleteDirectory(file);
                }
            }
            directory.delete();
        }
    }

